const objectTypes = {
    'boolean': false,
    'function': true,
    'object': true,
    'number': false,
    'string': false,
    'undefined': false
};
const __heads=['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'];
const __headsize=__heads.length;
const rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;
const  class2type = {};
const toString = class2type.toString;
const hasOwn = class2type.hasOwnProperty;

function AZToNum(str){
    let i=0;
    for(;i<__headsize;i++){
        if(__heads[i]==s) return i+1;
    }
    return 0;
}
function NumToAZ(n){
    return __heads[n-1];
}

class Tools {
	constructor(){}
	static uuid(len, radix){
        let chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
	    let uuid = [], i;
	    radix = radix || chars.length;
	    if (len) {
            // Compact form
            for (i = 0; i < len; i++) uuid[i] = chars[0 | Math.random()*radix];
	    } else {
	        // rfc4122, version 4 form
	        let r;
            // rfc4122 requires these characters
            uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
            uuid[14] = '4';
            // Fill in random data.  At i==19 set the high bits of clock sequence as
            // per rfc4122, sec. 4.1.5
            for (i = 0; i < 36; i++) {
                if (!uuid[i]) {
                    r = 0 | Math.random()*16;
                    uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r];
                }
            }
	    }
	    return uuid.join('');
    }
    static trim(text){
        return text == null ? "" : ( text + "" ).replace( rtrim, "" );
    }
    static extend(){
        /*
        　　*target被扩展的对象
        　　*length参数的数量
        　　*deep是否深度操作
        　　*/
        let options, name, src, copy, copyIsArray, clone,
    　　　　target = arguments[0] || {},
    　　　　i = 1,
    　　　　length = arguments.length,
    　　　　deep = false;

    　　if ( typeof target === "boolean" ) {
    　　　　deep = target;
    　　　　target = arguments[1] || {};
    　　　　i = 2;
    　　}
    　　if ( typeof target !== "object" && !this.isFunction(target) ) {
        　　target = {};
    　　}
    　　if ( length === i ) {
    　　　　target = this;
    　　　　--i;
    　　}
    　　for ( ; i < length; i++ ) {
    　　　　if ( (options = arguments[ i ]) != null ) {
    　　　　　　for ( name in options ) {
    　　　　　　　　src = target[ name ];
    　　　　　　　　copy = options[ name ];
    　　　　　　　　if ( target === copy ) {
    　　　　　　　　　　continue;
    　　　　　　　　}
    　　　　　　　　if ( deep && copy && ( this.isPlainObject(copy) || (copyIsArray = this.isArray(copy)) ) ) {
    　　　　　　　　　　// 如果是数组
    　　　　　　　　　　if ( copyIsArray ) {
    　　　　　　　　　　　　copyIsArray = false;
    　　　　　　　　　　　　clone = src && this.isArray(src) ? src : [];
    　　　　　　　　　　} else {
    　　　　　　　　　　　　clone = src && this.isPlainObject(src) ? src : {};
    　　　　　　　　　　}
    　　　　　　　　　　target[ name ] = this.extend( deep, clone, copy );
    　　　　　　　　} else if ( copy !== undefined ) {
    　　　　　　　　　　target[ name ] = copy;
    　　　　　　　　}
    　　　　　　}
    　　　　}
    　　}
    　　return target;
    }
    static isEmptyObject(obj){
        let name;
        for ( name in obj ) {
            return false;
        }
        return true;
    }
    static type(obj){
        if ( obj == null ) {
            return obj + "";
        }
        // Support: Android<4.0, iOS<6 (functionish RegExp)
        return typeof obj === "object" || typeof obj === "function" ?
            class2type[ toString.call( obj ) ] || "object" :
            typeof obj;  
    }
    static isFunction(obj){
        return this.type( obj ) === "function";
    }
    static isPlainObject(obj){
        let key;
        // Not plain objects:
        // - Any object or value whose internal [[Class]] property is not "[object Object]"
        // - DOM nodes
        // - window
        if ( this.type( obj ) !== "object" || obj.nodeType || this.isWindow( obj ) ) {
            return false;
        }
        // Not own constructor property must be Object
        if ( obj.constructor &&
                !hasOwn.call( obj, "constructor" ) &&
                !hasOwn.call( obj.constructor.prototype || {}, "isPrototypeOf" ) ) {
            return false;
        }
        // Own properties are enumerated firstly, so to speed up,
        // if last one is own, then all properties are own
        for ( key in obj ) {}
        return key === undefined || hasOwn.call( obj, key );
    }
    static isObject(value){
        return !!(value && objectTypes[typeof value]);
    }
    static isArray(obj){
        return Array.isArray(obj);
    }
    static isWindow( obj ) {
        return obj != null && obj === obj.window;
    }
    static isDate(input) {
    	return Object.prototype.toString.call(input) === '[object Date]' || input instanceof Date;
  	}
    //样式对象序列化
  	static styleFmt(styles){
  		let style='';
	    if(this.isObject(styles)==true){
	      for(let i in styles){
	        style+=i+':'+styles[i]+' !important;';
	      }
	    }
	    return style
  	}
  	// 以下方法实现创建Excel表头[A-Z]
   	// 包含文本到坐标体系的转换和坐标体系到文本的转换
   	static labelToNum(s){
   		let num=0;
	    if(s==""||s==undefined){
	      return num;
	    }
	    s=s.toUpperCase();
	    for (let i = s.length - 1, j = 1; i >= 0; i--, j *= 26){
	      num += AZToNum(s[i]) * j;
	    }
	    return num;
	}
    static numToLabel(n){
        let s='';
        while (n > 0){
            let m = n % __headsize;
            if (m == 0) m = __headsize;
            s = NumToAZ(m) + s;
            n = (n - m) / __headsize;
        }
        return s;
    }

    static generateSheets(name,enname,type,desc,state,r,c,ch,rh,d){
        let tempdata={
            id:this.uuid(),
            name:name,
            type:type, //
            desc:desc,
            dbname:enname,
            dbid:'',
            state:state||0, //0:新创建 1:已保存 2:临时模板
            sheets:[
                {
                    id:this.uuid(),
                    name:name||'new sheet',
                    colheader:ch||null,
                    rowheader:rh||null,
                    data:d||{},
                    mergecells:[],
                    groups:{}, //id,name,type,legend[],category[],value[]
                    minrows:r||30,
                    mincols:c||26
                }
            ]
        };
        return tempdata
    }

    static generateSheet(id,name,ch,rh,d,r,c){
        return {
                    id:id||this.uuid(),
                    name:name||'new sheet',
                    colheader:ch||null,
                    rowheader:rh||null,
                    data:d||{},
                    mergecells:[],
                    groups:{}, //id,name,type,legend[],category[],value[]
                    minrows:r||30,
                    mincols:c||26
                }
    }

    static getBtnCls(evt){
        let cls;
        switch(evt){
            case 'cancel':
            cls='btn btn-warning';
            break;
            case 'test':
            cls='btn btn-info';
            break;
            case 'del':
            cls='btn btn-danger';
            break;
            case 'link':
            cls='btn btn-link';
            break;
            default:
            cls='btn btn-primary';
            break;
        }
        return cls;
    }

    static newcell(r,c,t,v,hv,readonly){
        v=v===undefined||v===null?null:v;
        return {
            //基本属性
            id:this.uuid(),
            c:c,          //列
            r:r,          //行
            value:v||null,   //值
            formula:null, //公式
            type:t||'text', //text||numeric||checkbox||date||select||dropdown||autocomplete||password||head
            tips:null,    //备注提示
            readonly:readonly||false,
            styles:{
                'font-weight':''
				,'font-style':''
				,'text-decoration':''
				,'text-align':''
				,'color':''
				,'background-color':''
            },
            //数据库配置
            dbopts:{
                type:'',
				field:'',
				comment:'',
				value:hv||''
            }
            // 验证
            , verify:null
        };
    }
}

export default Tools; 